//
//  MenuViewController.m
//  PriceOnline
//
//  Created by Le Anh Tai on 8/13/14.
//  Copyright (c) 2014 Le Anh Tai. All rights reserved.
//

#import "MenuViewController.h"
#import "Utility.h"
#import "Reachability.h"
#import "MBProgressHUD.h"
#import "Global.h"
#import "WebsiteCell.h"
#import "HeaderView.h"

#define FAVOURITE_INDEX 0
#define OTHER_INDEX 1
#define HEI_SEARCH 40

#define EDIT_TEXT @"SỬA"
#define CANCEL_TEXT @"HỦY"

@interface MenuViewController ()

@end

@implementation MenuViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    _originalFavouriteWebsites = [[NSMutableArray alloc] init];
    _originalOtherWebsites = [[NSMutableArray alloc] init];
    _favouriteWebsites = [[NSMutableArray alloc] init];
    _otherWebsites = [[NSMutableArray alloc] init];
    _sections = @[_favouriteWebsites, _otherWebsites];
    
    [self prepareData];
	
    _alphaView = [[UIView alloc] init];
    _alphaView.backgroundColor = [UIColor clearColor];
    [self.view insertSubview:_alphaView belowSubview:_contentView];
    
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureHandler:)];
    [_alphaView addGestureRecognizer:tapGesture];

    _contentView.backgroundColor = [UIColor darkGrayColor];
    _contentView.layer.masksToBounds = NO;
    _contentView.layer.shadowOffset = CGSizeMake(8, 0);
    _contentView.layer.shadowOpacity = 0.4;
    
    _tableView = [[UITableView alloc] init];
    _tableView.backgroundColor = [UIColor clearColor];
    _tableView.dataSource = self;
    _tableView.delegate = self;
    _tableView.backgroundView = nil;
    _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    _tableView.allowsSelectionDuringEditing = YES;
    _tableView.showsVerticalScrollIndicator = NO;
    [_contentView addSubview:_tableView];
    
    _tableView.contentInset = UIEdgeInsetsMake(HEI_SEARCH, 0, 0, 0);
    _tableView.contentOffset = POINT(0, -HEI_SEARCH);
    
    UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGestureHandler:)];
    swipeGesture.direction = UISwipeGestureRecognizerDirectionLeft;
    [self.view addGestureRecognizer:swipeGesture];
    
    UITapGestureRecognizer *tapHeaderGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapHeaderGestureHandler:)];
    tapHeaderGesture.delegate = self;
    [self.view addGestureRecognizer:tapHeaderGesture];
    
    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressGestureRecognized:)];
    [_tableView addGestureRecognizer:longPress];
    
    [self initializeTitle];
    
    _lineView = [[UIView alloc] init];
    _lineView.backgroundColor = [UIColor clearColor];
    [_contentView addSubview:_lineView];
    
    _lineRightView = [[UIView alloc] init];
    _lineRightView.backgroundColor = [UIColor clearColor];
    [_contentView addSubview:_lineRightView];
    
    _searchBar = [[UISearchBar alloc] init];
    _searchBar.barStyle = UIBarStyleBlackOpaque;
    _searchBar.delegate = self;
    _searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
    _searchBar.autocapitalizationType = UITextAutocapitalizationTypeNone;
    _searchBar.showsCancelButton = NO;
    _searchBar.placeholder = @"Tìm website";
    [_contentView addSubview:_searchBar];
    
    [self initializeRightButton];
    
    [self initializeLeftButton];
    
    // Selected default
    NSIndexPath *defaultSelectedIndex = [self getTopWebsiteIndex];
    
    if (defaultSelectedIndex) {
        [self selectWebsiteAtIndex:defaultSelectedIndex];
        [self highlightCellAtIndextPath:defaultSelectedIndex];
    }
}

- (NSIndexPath *)getTopWebsiteIndex {
    NSIndexPath *topIndex = nil;
    
    if (_favouriteWebsites.count > 0) {
        topIndex = [NSIndexPath indexPathForRow:0 inSection:0];
    }
    else if (_otherWebsites.count > 0) {
        topIndex = [NSIndexPath indexPathForRow:0 inSection:1];
    }
    
    return topIndex;
}

- (void)highlightCellAtIndextPath:(NSIndexPath *)index
{
    [_tableView selectRowAtIndexPath:index animated:NO scrollPosition:UITableViewScrollPositionNone];
}

- (void)initializeTitle
{
    _titleLabel = [[UILabel alloc] init];
    _titleLabel.text = @"Báo VN";//(NSString *)[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"];
    _titleLabel.font = FONT_BOLD(15);
    _titleLabel.textAlignment = NSTextAlignmentCenter;
    _titleLabel.backgroundColor = [UIColor clearColor];
    _titleLabel.textColor = [UIColor greenColor];
    [_contentView addSubview:_titleLabel];
}

- (void)initializeRightButton
{
    _rightButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [_rightButton setTitle:EDIT_TEXT forState:UIControlStateNormal];
    [_rightButton setTitle:DONE_TEXT forState:UIControlStateSelected];
    [_rightButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    _rightButton.titleLabel.font = FONT(13);
    [_rightButton addTarget:self action:@selector(editButtonPressed) forControlEvents:UIControlEventTouchUpInside];
    [_contentView addSubview:_rightButton];
}

- (void)initializeLeftButton
{
    _leftButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [_leftButton setTitle:CANCEL_TEXT forState:UIControlStateNormal];
    [_leftButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [_leftButton addTarget:self action:@selector(cancelButtonPressed) forControlEvents:UIControlEventTouchUpInside];
    _leftButton.hidden = YES;
    _leftButton.titleLabel.font = FONT(13);
    [_contentView addSubview:_leftButton];
}

- (void)prepareData
{
    [self loadFavouriteWebsites];
    [self loadOtherWebsites];
}

- (void)loadFavouriteWebsites
{
    if (_markedWebsite == nil)
    {
        NSArray *markedWebsites = [[CoreData shared] fetchEntity:MARKED_WEBSITE_ENTITY];
        if (markedWebsites.count == 0)
        {
            return;
        }
        
        _markedWebsite = [markedWebsites objectAtIndex:0];
    }
    
    NSArray *websites = [[_markedWebsite valueForKey:WEBSITE_KEY] allObjects];
    
    //order accending
    websites = [websites sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        NSNumber *order1 = [obj1 valueForKey:ORDER_KEY];
        NSNumber *order2 = [obj2 valueForKey:ORDER_KEY];
        
        return [order1 compare:order2];
    }];
    
    _originalFavouriteWebsites = [[NSMutableArray alloc] initWithArray:websites];
    
    [_favouriteWebsites removeAllObjects];
    [_favouriteWebsites addObjectsFromArray:[[NSMutableArray alloc] initWithArray:_originalFavouriteWebsites]];
}

- (void)loadOtherWebsites
{
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"markedWebsite == nil"];
    NSArray *websites = [[CoreData shared] fetchEntity:WEBSITE_ENTITY withPredicate:predicate sortAttribute:ICON_KEY isAscending:YES];
    if (websites.count == 0)
    {
        return;
    }
    
    _originalOtherWebsites = [[NSMutableArray alloc] initWithArray:websites];
    
    [_otherWebsites removeAllObjects];
    [_otherWebsites addObjectsFromArray:[[NSMutableArray alloc] initWithArray:_originalOtherWebsites]];
}

- (void)reloadData
{
    [self prepareData];
    [_tableView reloadData];
    [[CoreData shared] saveContext];
}

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    
    NSInteger padding = 8;
    NSInteger widEditButton = 50;
    NSInteger widCancelButton = 70;
    NSInteger top = 0;
    NSInteger heiTitle = 34;
    NSInteger widTable = MENU_WID;
    
    if (IS_SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_IOS7)
    {
        top = 20;
    }
    
    _alphaView.frame = self.view.bounds;
    
    _contentView.width = widTable;
    
    _titleLabel.frame = RECT(0, top, _contentView.width, heiTitle);
    _lineView.frame = RECT(padding, _titleLabel.bottom, widTable - padding*2, 1);
    _lineRightView.frame = RECT(_lineView.right, _lineView.top, 1, _contentView.height);
    _tableView.frame = RECT(0, _lineView.bottom, _contentView.width, _contentView.height - _lineView.bottom);
    _searchBar.frame = RECT(0, _tableView.top, _tableView.width, HEI_SEARCH);
    _rightButton.frame = RECT(_contentView.width - widEditButton, _titleLabel.top, widEditButton, _titleLabel.height);
    _leftButton.frame = RECT(0, _titleLabel.top, widCancelButton, _titleLabel.height);
}

- (void)animateOut
{
    self.view.hidden = NO;
    _alphaView.alpha = 0;
    _contentView.right = 0;
    
    if ([_delegateMenu respondsToSelector:@selector(menuControllerWillShow:)])
    {
        [_delegateMenu menuControllerWillShow:self];
    }
    
    [UIView animateWithDuration:0.3 animations:^{
        _alphaView.alpha = 0.65;
        _contentView.left = 0;
    }];
}

- (void)animateInAndHide
{
    if ([_delegateMenu respondsToSelector:@selector(menuControllerWillHide:)])
    {
        [_delegateMenu menuControllerWillHide:self];
    }
    
    [UIView animateWithDuration:0.3 animations:^{
        _alphaView.alpha = 0;
        _contentView.right = 0;
    } completion:^(BOOL finished) {
        self.view.hidden = YES;
    }];
}

- (void)resetOrderWebsites
{
    int i = 0;
    for (NSManagedObject *site in _originalFavouriteWebsites)
    {
        [site setValue:[NSNumber numberWithInt:i] forKey:ORDER_KEY];
        i++;
    }
    
    [[CoreData shared] saveContext];
}

- (void)selectWebsiteAtIndex:(NSIndexPath *)indexPath
{
    NSArray *website = [_sections objectAtIndex:indexPath.section];
    _selectedWebsiteData = [website objectAtIndex:indexPath.row];
    
    if ([_delegateMenu respondsToSelector:@selector(menuController:didSelectWebsite:)])
    {
        [_delegateMenu menuController:self didSelectWebsite:_selectedWebsiteData];
    }
}

#pragma mark -
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]])
    {
        CGPoint point = [gestureRecognizer locationInView:self.view];
        
        CGRect rectHeader = RECT(0, 0, self.view.width, MIN(_titleLabel.bottom, 30));
        
        if ( CGRectContainsPoint(rectHeader, point) )
        {
            return YES;
        }
        else
        {
            return NO;
        }
    }
    
    return NO;//[super gestureRecognizerShouldBegin:gestureRecognizer];
}

- (void)tapHeaderGestureHandler:(UITapGestureRecognizer *)gestureRecognizer
{
    CGPoint point = [gestureRecognizer locationInView:self.view];
    
    CGRect rectHeader = RECT(0, 0, self.view.width, MIN(_titleLabel.bottom, 30));
    
    if ( CGRectContainsPoint(rectHeader, point) )
    {
        NSIndexPath *defaultSelectedIndex = [self getTopWebsiteIndex];
        
        if (defaultSelectedIndex) {
            [_tableView scrollToRowAtIndexPath:defaultSelectedIndex
                              atScrollPosition:UITableViewScrollPositionBottom
                                      animated:YES];
        }
    }
}

- (void)swipeGestureHandler:(UISwipeGestureRecognizer *)sender
{
    [self animateInAndHide];
}

- (void)tapGestureHandler:(UITapGestureRecognizer *)sender
{
    [self animateInAndHide];
}

- (void)editButtonPressed
{
    [_rightButton setSelected:!_rightButton.selected];
    BOOL isEdit = _rightButton.selected;
    
    _leftButton.hidden = !isEdit;
    
    [_tableView setEditing:isEdit animated:YES];
    
    //click done
    if (_rightButton.selected == NO)
    {
        BOOL hasRemoveFromFavourite = NO;
        BOOL hasRemoveFromOther = NO;
        
        //remove from favourite
        for (NSInteger i = _originalFavouriteWebsites.count - 1; i >= 0; i--)
        {
            NSManagedObject *website = [_originalFavouriteWebsites objectAtIndex:i];
            if ([website valueForKey:MARKED_WEBSITE_KEY] == nil)
            {
                hasRemoveFromFavourite = YES;
                [_originalFavouriteWebsites removeObject:website];
            }
        }
        
        //remove from other
        for (NSInteger i = _originalOtherWebsites.count - 1; i >=0 ; i--)
        {
            NSManagedObject *website = [_originalOtherWebsites objectAtIndex:i];
            if ([website valueForKey:MARKED_WEBSITE_KEY])
            {
                hasRemoveFromOther = YES;
                [_originalFavouriteWebsites addObject:website];
            }
        }
        
        if (hasRemoveFromFavourite || hasRemoveFromOther)
        {
            [self resetOrderWebsites];
            
            [self loadFavouriteWebsites];
            [self loadOtherWebsites];
            
            [_tableView reloadData];
            
            NSIndexPath *defaultSelectedIndex = [self getTopWebsiteIndex];
            
            if (defaultSelectedIndex) {
                [_tableView scrollToRowAtIndexPath:defaultSelectedIndex
                              atScrollPosition:UITableViewScrollPositionBottom
                                      animated:YES];
            }
        }
        
        [self searchBar:_searchBar textDidChange:_searchBar.text];
    }
}

- (void)cancelButtonPressed
{
    for (NSManagedObject *website in _originalFavouriteWebsites)
    {
        [website setValue:_markedWebsite forKey:MARKED_WEBSITE_KEY];
    }
    
    for (NSManagedObject *website in _originalOtherWebsites)
    {
        [website setValue:nil forKey:MARKED_WEBSITE_KEY];
    }
    
    [_tableView reloadData];
    [_tableView setEditing:NO animated:YES];
    [_rightButton setSelected:NO];
    _leftButton.hidden = YES;
}

#pragma mark - Delegate UITableView
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    _tableView.contentInset = UIEdgeInsetsMake(HEI_SEARCH, 0, 0, 0);
    
    return _sections.count;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    HeaderView *headerView = [[HeaderView alloc] init];
    headerView.backgroundColor = [UIColor blackColor];
    
    if (section == FAVOURITE_INDEX)
    {
        headerView.titleLabel.text = @"Trang yêu thích";
    }
    else if (section == OTHER_INDEX)
    {
        headerView.titleLabel.text = @"Trang khác";
    }
    
    return headerView;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 24;
}

- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
{
    NSArray *websites = [_sections objectAtIndex:section];
    return websites.count;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return LOGO_HEI + LOGO_MARGIN;
}

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"WebsiteSite";
    
    //reuse cell cause error "allow move cell in other websites"
    WebsiteCell *cell = [[WebsiteCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];;
    
    NSArray *websites = [_sections objectAtIndex:indexPath.section];
    NSManagedObject *data = [websites objectAtIndex:indexPath.row];
    
    [cell loadData:data];
    
    if (data == _selectedWebsiteData)
    {
        [self highlightCellAtIndextPath:indexPath];
    }
    
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (tableView.isEditing)
    {
        NSArray *section = [_sections objectAtIndex:indexPath.section];
        NSManagedObject *website = [section objectAtIndex:indexPath.row];
        NSManagedObject *marked = [website valueForKey:MARKED_WEBSITE_KEY];
        
        if (marked)
        {
            [website setValue:nil forKey:MARKED_WEBSITE_KEY];
        }
        else
        {
            [website setValue:_markedWebsite forKey:MARKED_WEBSITE_KEY];
        }
        
        WebsiteCell *cell = (WebsiteCell *)[tableView cellForRowAtIndexPath:indexPath];
        [cell loadData:website];
    }
    else
    {
        if ([_searchBar isFirstResponder])
        {
            [_searchBar resignFirstResponder];
        }
        
        [self selectWebsiteAtIndex:indexPath];
        [self animateInAndHide];
    }
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSArray *websites = [_sections objectAtIndex:indexPath.section];
    NSManagedObject *website = [websites objectAtIndex:indexPath.row];
    [website setValue:nil forKey:MARKED_WEBSITE_KEY];
    
    [self prepareData];
    
    [self resetOrderWebsites];
    
    [tableView beginUpdates];
    
    [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
    
    [tableView endUpdates];
}

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewCellEditingStyleNone;
}

- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
    if (proposedDestinationIndexPath.section == OTHER_INDEX)
    {
        return sourceIndexPath;
    }
    
    return proposedDestinationIndexPath;
}

//- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
//{
//    if (toIndexPath.section == OTHER_INDEX)
//    {
//        return;
//    }
//    
//    NSManagedObject *itemFrom = [_favouriteWebsites objectAtIndex:fromIndexPath.row];
//    NSManagedObject *itemTo = [_favouriteWebsites objectAtIndex:toIndexPath.row];
//    
//    if ([itemFrom isEqual:itemTo])
//    {
//        return;
//    }
//    
//    [_favouriteWebsites removeObject:itemFrom];
//    [_originalFavouriteWebsites removeObject:itemFrom];
//    
//    NSInteger insertIndex = [_favouriteWebsites indexOfObject:itemTo];
//    NSInteger originalInsertIndex = [_originalFavouriteWebsites indexOfObject:itemTo];
//    
//    if (fromIndexPath.row < toIndexPath.row)
//    {
//        //because of removing one objec so +1
//        insertIndex++;
//        originalInsertIndex++;
//    }
//    
//    [_favouriteWebsites insertObject:itemFrom atIndex:insertIndex];
//    [_originalFavouriteWebsites insertObject:itemFrom atIndex:originalInsertIndex];
//    
//    [self resetOrderWebsites];
//}

//- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
//{
//    if (indexPath.section == FAVOURITE_INDEX)
//    {
//        return YES;
//    }
//    
//    return NO;
//}
//

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    [_searchBar resignFirstResponder];
}

#pragma mark - Delegate


#pragma mark -
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
    // only show the status bar's cancel button while in edit mode
    _searchBar.showsCancelButton = YES;
}

- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
    _searchBar.showsCancelButton = NO;
}

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    if (searchText.length == 0)
    {
        [self resetSearchFilter];
        
        return;
    }
    
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self.url CONTAINS[c] %@", searchText];
    NSArray *filterFavourites = [_originalFavouriteWebsites filteredArrayUsingPredicate:predicate];
    NSArray *filterOthers = [_originalOtherWebsites filteredArrayUsingPredicate:predicate];
    
    [_favouriteWebsites removeAllObjects];
    [_favouriteWebsites addObjectsFromArray:filterFavourites];
    
    [_otherWebsites removeAllObjects];
    [_otherWebsites addObjectsFromArray:filterOthers];
    
    [_tableView reloadData];
}

- (void)resetSearchFilter
{
    [_favouriteWebsites removeAllObjects];
    [_favouriteWebsites addObjectsFromArray:_originalFavouriteWebsites];
    
    [_otherWebsites removeAllObjects];
    [_otherWebsites addObjectsFromArray:_originalOtherWebsites];
    
    [_tableView reloadData];
}

// called when cancel button pressed
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
    [searchBar resignFirstResponder];
    
    searchBar.text = @"";
    [self resetSearchFilter];
}

//Search button pressed
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
    [searchBar resignFirstResponder];
}

- (IBAction)longPressGestureRecognized:(id)sender
{
    
    UILongPressGestureRecognizer *longPress = (UILongPressGestureRecognizer *)sender;
    UIGestureRecognizerState state = longPress.state;
    
    CGPoint location = [longPress locationInView:_tableView];
    NSIndexPath *indexPath = [_tableView indexPathForRowAtPoint:location];
    
    static UIView      *snapshot = nil;        ///< A snapshot of the row user is moving.
    static NSIndexPath  *sourceIndexPath = nil; ///< Initial index path, where gesture begins.
    
    switch (state)
    {
        case UIGestureRecognizerStateBegan:
        {
            if (indexPath)
            {
                sourceIndexPath = indexPath;
                
                UITableViewCell *cell = [_tableView cellForRowAtIndexPath:indexPath];
                
                // Take a snapshot of the selected row using helper method.
                snapshot = [self customSnapshoFromView:cell];
                
                // Add the snapshot as subview, centered at cell's center...
                __block CGPoint center = cell.center;
                snapshot.center = center;
                snapshot.alpha = 0.0;
                [_tableView addSubview:snapshot];
                [UIView animateWithDuration:0.25 animations:^{
                    
                    // Offset for gesture location.
                    center.y = location.y;
                    snapshot.center = center;
                    snapshot.transform = CGAffineTransformMakeScale(1.1, 1.1);
                    snapshot.alpha = 0.98;
                    cell.alpha = 0.0;
                    
                } completion:^(BOOL finished) {
                    
                    cell.hidden = YES;
                    
                }];
            }
            break;
        }
            
        case UIGestureRecognizerStateChanged: {
            NSIndexPath *locationIndexPath = [_tableView indexPathForRowAtPoint:location];
            if (locationIndexPath.section > 0)
            {
                break;
            }
            
            CGPoint center = snapshot.center;
            center.y = location.y;
            snapshot.center = center;
            
            [_tableView scrollRectToVisible:snapshot.frame animated:NO];
            
            // Is destination valid and is it different from source?
            if (indexPath && ![indexPath isEqual:sourceIndexPath]) {
                
                // ... update data source.
                id obj = [_favouriteWebsites objectAtIndex:indexPath.row];
                id sourceObj = [_favouriteWebsites objectAtIndex:sourceIndexPath.row];
                NSInteger originalIndex = [_originalFavouriteWebsites indexOfObject:obj];
                NSInteger originalSourceIndex = [_originalFavouriteWebsites indexOfObject:sourceObj];
                
                [_originalFavouriteWebsites exchangeObjectAtIndex:originalIndex withObjectAtIndex:originalSourceIndex];
                [_favouriteWebsites exchangeObjectAtIndex:indexPath.row withObjectAtIndex:sourceIndexPath.row];
                
                
                // ... move the rows.
                [_tableView moveRowAtIndexPath:sourceIndexPath toIndexPath:indexPath];
                
                // ... and update source so it is in sync with UI changes.
                sourceIndexPath = indexPath;
            }
            break;
        }
            
        default: {
            // Clean up.
            UITableViewCell *cell = [_tableView cellForRowAtIndexPath:sourceIndexPath];
            cell.hidden = NO;
            cell.alpha = 0.0;
            
            [UIView animateWithDuration:0.25 animations:^{
                
                snapshot.center = cell.center;
                snapshot.transform = CGAffineTransformIdentity;
                snapshot.alpha = 0.0;
                cell.alpha = 1.0;
                
            } completion:^(BOOL finished) {
                
                sourceIndexPath = nil;
                [snapshot removeFromSuperview];
                snapshot = nil;
                
                [self resetOrderWebsites];
            }];
            
            break;
        }
    }
}

#pragma mark - Helper methods

/** @brief Returns a customized snapshot of a given view. */
- (UIView *)customSnapshoFromView:(UIView *)inputView
{
    // Make an image from the input view.
    UIGraphicsBeginImageContextWithOptions(inputView.bounds.size, NO, 0);
    [inputView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    // Create an image view.
    UIView *snapshot = [[UIImageView alloc] initWithImage:image];
    snapshot.layer.masksToBounds = NO;
    snapshot.layer.cornerRadius = 0.0;
    snapshot.layer.shadowOffset = CGSizeMake(-3.0, 0.0);
    snapshot.layer.shadowRadius = 5.0;
    snapshot.layer.shadowOpacity = 0.4;
    
    return snapshot;
}
@end
